﻿using System;
using System.Collections.Generic;
using System.IO;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using YArchitech.Revit;

namespace HYFamilyLibDataManager
{
	public class DbFamilySymbol
	{
		public string Name
		{
			get
			{
				return this.mName;
			}
		}

		public DbFamily Family
		{
			get
			{
				return this.mFamily;
			}
		}

		public FamilyLibDatabase Database
		{
			get
			{
				return this.mDatabase;
			}
		}

		public void SetDatabase(FamilyLibDatabase db)
		{
			this.mDatabase = db;
		}

		public DbFamilySymbol(DbFamily family, string name)
		{
			this.mFamily = family;
			this.mName = name;
		}

		public FamilySymbol Create1(Autodesk.Revit.DB.Document doc)
		{
			FileInfo fileInfo = null;
			Family family = this.Family.Load(doc, ref fileInfo);
			if (FamilyUtil.FindSymbol(family, this.mName) == null && FamilyUtil.FindSymbol(family, this.mName.ToUpper()) == null && FamilyUtil.FindSymbol(family, this.mName.ToLower()) == null)
			{
				FamilySymbol familySymbol = null;
				foreach (FamilySymbol familySymbol2 in family.GetSymbols())
				{
					if (familySymbol2 != null)
					{
						familySymbol = familySymbol2;
						break;
					}
				}
				Transaction transaction = new Transaction(doc, "NewType");
				transaction.Start();
				Autodesk.Revit.DB.ElementType elem = familySymbol.Duplicate(this.mName);
				foreach (DbParameter dbParameter in this.Params)
				{
					if (dbParameter.Value != null && Convert.ToString(dbParameter.Value) != "" && dbParameter.ParamDefinition != null)
					{
						try
						{
							Parameter parameter = elem.GetParameter(dbParameter.ParamDefinition.Name);
                            switch ((int)parameter.StorageType)
							{
							case 1:
								parameter.Set(Convert.ToInt32(dbParameter.Value));
								break;
							case 2:
								parameter.Set(Convert.ToDouble(dbParameter.Value) / Convert.ToDouble(UnitConvertC.ImperialDutRatio(dbParameter.ParamDefinition.DisplayUnitType)));
								break;
							case 3:
								parameter.Set(Convert.ToString(dbParameter.Value));
								break;
							case 4:
							{
								object value = dbParameter.Value;
								break;
							}
							}
						}
						catch
						{
						}
					}
				}
				transaction.Commit();
			}
			FamilySymbol result = FamilyUtil.FindSymbol(family, this.mName);
			this.Family.UseCountAndDatePlus();
			return result;
		}

		public FamilySymbol Create(Autodesk.Revit.DB.Document doc)
		{
			Family family = this.Family.Load(doc);
			if (FamilyUtil.FindSymbol(family, this.mName) == null && FamilyUtil.FindSymbol(family, this.mName.ToUpper()) == null && FamilyUtil.FindSymbol(family, this.mName.ToLower()) == null)
			{
				FamilySymbol familySymbol = null;
				foreach (FamilySymbol familySymbol2 in family.GetSymbols())
				{
					if (familySymbol2 != null)
					{
						familySymbol = familySymbol2;
						break;
					}
				}
				Transaction transaction = new Transaction(doc, "NewType");
				transaction.Start();
				Autodesk.Revit.DB.ElementType elem = familySymbol.Duplicate(this.mName);
				foreach (DbParameter dbParameter in this.Params)
				{
					if (dbParameter.Value != null && Convert.ToString(dbParameter.Value) != "" && dbParameter.ParamDefinition != null)
					{
						try
						{
							Parameter parameter = elem.GetParameter(dbParameter.ParamDefinition.Name);
                            switch ((int)parameter.StorageType)
							{
							case 1:
								parameter.Set(Convert.ToInt32(dbParameter.Value));
								break;
							case 2:
								parameter.Set(Convert.ToDouble(dbParameter.Value) / Convert.ToDouble(UnitConvertC.ImperialDutRatio(dbParameter.ParamDefinition.DisplayUnitType)));
								break;
							case 3:
								parameter.Set(Convert.ToString(dbParameter.Value));
								break;
							case 4:
							{
								object value = dbParameter.Value;
								break;
							}
							}
						}
						catch
						{
						}
					}
				}
				transaction.Commit();
			}
			FamilySymbol result = FamilyUtil.FindSymbol(family, this.mName);
			this.Family.UseCountAndDatePlus();
			return result;
		}

		public FamilySymbol Create(Autodesk.Revit.DB.Document doc, ref int host)
		{
			Parameter parameter = this.Family.Load(doc).get_Parameter(BuiltInParameter.FAMILY_HOSTING_BEHAVIOR);
			if (parameter != null)
			{
				host = parameter.AsInteger();
			}
			return this.Create(doc);
		}

		public void Place(UIDocument uiDoc)
		{
			try
			{
				uiDoc.PromptForFamilyInstancePlacement(this.Create(uiDoc.Document));
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
			}
		}

		public FamilyInstance Place(Autodesk.Revit.DB.Document doc, XYZ pt, Element host, StructuralType sType)
		{
			return doc.Create.NewFamilyInstance(pt, this.Create(doc), host, sType);
		}

		public override string ToString()
		{
			return this.mName;
		}

		public override int GetHashCode()
		{
			return base.GetHashCode();
		}

		protected string mName;

		protected DbFamily mFamily;

		protected FamilyLibDatabase mDatabase;

		public List<DbParameter> Params = new List<DbParameter>();
	}
}
